Control Towerカスタマイズソリューション(CfCT)を使ってガードレールとCloudFormationを自動展開してみた
Control Towerのカスタマイズという以下ソリューションを利用して、Control Tower配下のOUに対してCloudFormationスタックとSCPを自動展開してみました。
今回は以下のワークショップに沿って実施しています。単純な内容ですが、少しハマりどころもあったので手順含めて載せておきます。
AWS Control Towerのカスタマイズ (CfCT) :: AWS Control Tower ワークショップ
前提
- Control Tower有効化済(バージョン2.7)
- ホームリージョンは東京
構成
仕組みとしてはControl Towerからアカウントを発行した時やCodeCommitかS3のソースが更新されたとき、CloudFormationスタックやSCPを展開するというものです。
Control Towerのアカウントファクトリーからアカウントが発行された時には、ライフサイクルイベントcreateManagedAccountStatus
というイベントが発生します。発生したイベントをEventBridgeで取得してSQS、Lambdaと実行することでCodePipelineを新規アカウントに対し実行します。
CodePipelineではソースとなるS3かCodeCommitからテンプレートを取得してCodeBuildを実行しています。CodeBuildでは公開されているスクリプト群を取得して、StepFunctionsを動かすような仕組みとなっています。
このソリューションを利用することで、既存で管理しているアカウントや新規に発行したアカウントに対しても同じようにCloudFormationスタックやSCPを展開することが可能となります。
各リソースの詳細については実装ガイドを参照ください。
https://d1.awsstatic.com/Solutions/ja_JP/customizations-for-aws-control-tower.pdf
やってみた
今回はワークショップ通りに実施していくため、赤枠で囲ったCodeCommitへのPushからPipelineを実行してリソースを展開するフローを体験してみます。(新規アカウント発行からのフローについては別でまたブログを書きます。)
Control Towerが有効化されていることが前提です。
CfCTの展開
Control Towerのホームリージョンへ以下のリンクからスタックを展開します。このときリーションがホームリージョンとなっているか確認を忘れないようにしましょう。
AWS CodePipeline Source
にはS3ではなくCodeCommitを指定します。
その他はデフォルトのまま作成します。
次にCodeCommitへ接続する環境を用意します。Gitを利用できる環境であればどこでも構いませんが、今回はCloud9を使って実施しています。
Cloud9のCreate environment
から適当な名前を入力して起動してください。スペックなどはデフォルトで大丈夫です。
おそらくデフォルトで入っていますが念のため、以下のコマンドでGitをインストールします。
$ sudo yum install git -y
コンソールからCodeCommitの画面を開いて、custom-control-tower-configuration
のリポジトリからHTTPSのURLをコピーしてください。
コピーできたらCloud9のターミナルからクローンを実行します。
$ git clone {コピーしたHTTPSのURL}
ローカルにリポジトリのフォルダ(デフォルト:custom-control-tower-configuration)があることを確認してください。
カスタマイズソリューションを展開する
本来であれば、次の手順でmanifest.yaml
をワークショップ通りに上書きしてCodeCommitへPushするのですが、CodeBuildでエラーとなり実行できませんでした。
CodeBuildでは公開されているS3上のテンプレートをダウンロードして実行しており、そのURLを作成する過程でホームリージョンの東京リージョンを指定することが原因のようでした。(恐らくこのワークショップは東京リージョンをホームリージョンとして利用する想定となっていないため)
そのため、手動でテンプレートをダウンロードして、テンプレートファイルの指定をマニフェストファイルからS3ではなくローカルファイルへ変更してあげます。
今回は以下の方法で対応しました。
以下2つのテンプレートをダウンロードしてください。クリックでダウンロードできます。
Cloud9のクローンしたフォルダ配下にtemplate
フォルダを作成して、その中にダウンロードしたテンプレート2つをアップロードします。
クローンしたフォルダ直下にmanifest.yaml
ファイルがあるので、以下の内容で置き換えます。
organizational_units
とregions
については各自の環境に合わせて変更してください。
--- #Default region for deploying Custom Control Tower: Code Pipeline, Step functions, Lambda, SSM parameters, and StackSets region: ap-northeast-1 # Control Tower Home Region version: 2021-03-15 resources: # Control Tower Custom Service Control Policies - Additional Preventive Guardrails - name: test-preventive-guardrails description: To prevent from deleting or disabling resources in member accounts resource_file: s3://marketplace-sa-resources/ctlabs/preventive-guardrails.json deploy_method: scp #Apply to the following OU(s) deployment_targets: organizational_units: - Security # Control Tower Custom CloudFormation Resources - Create Additional IAM Role - name: create-iam-role resource_file: template/describe-regions-iam-role.template deploy_method: stack_set deployment_targets: organizational_units: - Security regions: - ap-northeast-1 # Control Tower Config Rule - Additional Detective Guardrails - name: rotate-access-keys-guardrail resource_file: template/access_keys_rotated.template parameters: - parameter_key: maxAccessKeyAge parameter_value: '24' deploy_method: stack_set deployment_targets: organizational_units: - Security regions: - ap-northeast-1
このマニフェストファイルではガードレールとIAMロールが指定したOU配下のアカウントへ展開されます。マニフェストファイルの書き方について詳細に知りたい方は以下開発者ガイドをご参照ください。(英語版)
customizations-for-aws-control-tower-developer-guide.pdf
日本語版の開発者ガイドもあるのですが、マニフェストファイルのバージョンが古くなっていました。記述方法が少し違うため、今のところは英語版を参照するのが良さそうです。
日本語版の開発者ガイドも最新バージョンとなっていたので、これから参照する場合は日本語の開発者ガイドを参照してください。
以下コマンドでCodeCommitにPushします。
git status git add -A git commit -m 'Initial checkin' git push
CodePipelineが動き始めるのでコンソールから確認して10分程度待ちましょう。マニフェストファイルが間違っていなければ問題なく成功するはずです。
展開した結果を確認する
Control Tower展開時に作成されるOUであるSecurity
を展開先と指定したので、Auditアカウントにログインして確認していきます。
ガードレールの展開
ガードレールとして展開されたSCPから確認してみます。OrganizationsのSCPを確認すると、test-preventive-guardrails
というマニフェストで指定した名前のSCPが展開されています。
中身を確認してみると、Security OUのみに展開されていることが確認できました。
StackSetsで展開されたリソース
展開されているIAMロールを確認してみます。StackSet-CustomControlTower-create-TestLambdaRole-XXXXXXXXXX
というロールがStackSetsより展開されていることが確認できます。
もう1つ展開されているConfigルールを確認します。Configを開くとACCESS_KEYS_ROTATED
というルールが展開されています。
中身を見ると、マニフェストで指定したパラメータが確認できました。
ここまででワークショップは終了です。展開されている2つのStackSetsはControl Towerのマネジメントアカウントから確認できます。
マニフェストファイルを修正して再Push
せっかくなのでマニフェストファイルの値を変更したとき、正しく各アカウント側で修正されるか確認してみます。manifest.yaml
のparameter_value
を30に変更してみます。
# Control Tower Config Rule - Additional Detective Guardrails - name: rotate-access-keys-guardrail resource_file: template/access_keys_rotated.template parameters: - parameter_key: maxAccessKeyAge parameter_value: '30' deploy_method: stack_set deployment_targets: organizational_units: - Security regions: - ap-northeast-1
CodePipelineが問題なく完了したのを確認したら、同じようにAuditアカウントからConfigのルールを見てみます。
問題なくマニフェストファイルで指定した値が利用されて更新されていることが確認できました。
クリーンアップ
環境が不要な方は以下のクリーンアップ手順も実施してください。
SCPの削除
OrganizationsのSCPからtest-preventive-guardrails
を削除します。ターゲットから紐づいているOUをデタッチすればSCPを削除できます。
StackSetsの削除
Control Towerのマネジメントアカウントにログインして展開したStackSetsを削除します。
CloudFormation > StackSetsを確認してCustomControlTower-create-iam-role
にチェックを入れてアクションからスタックを削除します。
展開したOU単位、もしくはアカウント番号を入れて展開したリージョンを指定します。今回の例の通りであれば、リージョンは東京リージョンのみです。
その他はデフォルトで送信すると削除が実行されます。全てのスタックが削除されたらアクションからStackSetsの削除を選べば削除できます。同じ手順でCustomControlTower-rotate-access-keys-guardrail
も実施してください。
ソリューションスタックの削除
カスタマイズソリューション自体を削除します。CloudFormationからCustomizationsForCTSolution
のスタックを削除してください。
ただし、展開済のS3とCodeCommmitはスタックを削除しただけでは消えないので、不要であれば手動で削除してください。S3はバージョニングが有効化されているので、旧バージョンのオブジェクトまで全て削除してからバケットを削除するように注意しましょう。
対象のS3バケット
- custom-control-tower-configuration-{アカウントID}-{リージョン名}
- customizationsforctsolut-customcontroltowerpipeli-xxxxxxxxxxxx
- customizationsforctsolut-customcontroltowers3acce-xxxxxxxxxx
対象のリポジトリ名(CodeCommit)
- custom-control-tower-configuration
まとめ
Control Towerカスタマイズソリューション(CfCT)を使ってCloudFormationスタックとガードレールを展開してみました。Control Towerによる統制を考える際、同じリソースの展開やSCPの適用など各アカウントごとに実施する手間を減らすことができる良いソリューションだと感じました。
ただし、導入・運用するにあたりマニフェストファイルの書き方やソリューションの理解などが必要となるため少し学習コストが必要となることを忘れないようにしましょう。
マルチアカウント統制を考えるときの選択肢となれば幸いです。